package 多线程.线程池.定时器;

import java.util.PriorityQueue;

class Main2{
    public static void main(String[] args) {
        MyTimer myTimer = new MyTimer();
       /*
        myTimer.schedule(() -> System.out.println("8000"), System.currentTimeMillis() + 8000);
        myTimer.schedule(() -> System.out.println("4000"), System.currentTimeMillis() + 4000);
        myTimer.schedule(() -> System.out.println("2000"), System.currentTimeMillis() + 2000);
        myTimer.schedule(() -> System.out.println("1000"), System.currentTimeMillis() + 1000);*/
        myTimer.schedule(() -> System.out.println("8000"),  8000);
        myTimer.schedule(() -> System.out.println("4000"),  4000);
        myTimer.schedule(() -> System.out.println("2000"),  2000);
        myTimer.schedule(() -> System.out.println("1000"),  1000);
    }
}
public class MyTimerTask implements Comparable<MyTimerTask> {
    //定时器
    private long time;
    private Runnable runnable;
    public MyTimerTask(Runnable runnable,long time) {
        this.runnable = runnable;
        this.time = time;
    }
    public void run() {
        runnable.run();
    }
    public long getTime() {
        return time;
    }

    @Override
    public int compareTo(MyTimerTask o) {
        return (int)(this.time - o.time);
//        return (int)(o.time - this.time);
    }
}
class MyTimer {
    //使用优先级队列保存任务，按时间排序
    private PriorityQueue<MyTimerTask> taskQueue = new PriorityQueue<>();
    //不适合priorityBlockingQueue 只能处理队列为空 还会引入两把锁 容易死锁

    //创建锁对象
    private Object locker = new Object();

    //构造方法
    public MyTimer(){
        //线程不停地扫描队首元素
        Thread t = new Thread(() -> {
            try{
                while(true){
                    //枷锁
                    synchronized (locker){
                        if(taskQueue.size() == 0){
                            locker.wait();
                        }
                        //拿出队列队首的任务
                        MyTimerTask task = taskQueue.peek();

                        long curTime = System.currentTimeMillis();

                        if(curTime >= task.getTime()){
                            task.run();
                            taskQueue.poll();
                        }else{
                            //时间差 不能喝让wait死等
                            locker.wait(task.getTime() - curTime);
                        }
                    }
                }
            }catch(InterruptedException e){
                e.printStackTrace();
            }
        });
        t.start();
    }
    public void schedule(Runnable runnable,long time){
        synchronized (locker){
            MyTimerTask task = new MyTimerTask(runnable,time);
            taskQueue.offer(task);
            //有任务了就唤醒wait
            locker.notify();
        }

    }
}

